"""RPA框架机器人控制器组件"""

import time
import threading
from PyQt5.QtWidgets import (
    QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, 
    QGroupBox, QLineEdit, QTextEdit, QFormLayout, QComboBox,
    QSpinBox, QDoubleSpinBox, QProgressBar
)
from PyQt5.QtCore import Qt, pyqtSignal, QTimer
from PyQt5.QtGui import QColor, QFont, QPalette

from rpa_framework.core.robot import Robot
from rpa_framework.exceptions import RobotExecutionException
# 使用标准logging模块
import logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger("rpa.gui.robot_controller")


class RobotControllerWidget(QWidget):
    """机器人控制器组件"""
    
    # 定义信号
    robot_started = pyqtSignal(Robot)
    robot_stopped = pyqtSignal()
    robot_error = pyqtSignal(str)
    
    def __init__(self):
        super().__init__()
        
        # 机器人实例
        self.robot = None
        
        # 机器人运行线程
        self._robot_thread = None
        
        # 初始化UI
        self._init_ui()
        
        # 初始化定时器
        self._init_timer()
        
        # 更新UI状态
        self._update_ui_state()
    
    def _init_ui(self):
        """初始化UI组件"""
        main_layout = QVBoxLayout(self)
        
        # 机器人配置区域
        config_group = QGroupBox("机器人配置")
        config_layout = QFormLayout()
        
        # 机器人名称
        self.name_edit = QLineEdit("RPA机器人")
        config_layout.addRow("机器人名称:", self.name_edit)
        
        # 机器人描述
        self.description_edit = QLineEdit("自动执行RPA任务")
        config_layout.addRow("机器人描述:", self.description_edit)
        
        # 重试次数
        self.retry_spin = QSpinBox()
        self.retry_spin.setRange(0, 10)
        self.retry_spin.setValue(3)
        config_layout.addRow("默认重试次数:", self.retry_spin)
        
        # 重试间隔
        self.retry_interval_spin = QDoubleSpinBox()
        self.retry_interval_spin.setRange(0.1, 60)
        self.retry_interval_spin.setValue(1.0)
        self.retry_interval_spin.setSingleStep(0.5)
        config_layout.addRow("重试间隔(秒):", self.retry_interval_spin)
        
        # 超时时间
        self.timeout_spin = QSpinBox()
        self.timeout_spin.setRange(1, 3600)
        self.timeout_spin.setValue(300)
        config_layout.addRow("默认超时(秒):", self.timeout_spin)
        
        config_group.setLayout(config_layout)
        main_layout.addWidget(config_group)
        
        # 控制按钮区域
        control_layout = QHBoxLayout()
        
        # 启动按钮
        self.start_button = QPushButton("启动机器人")
        self.start_button.setFixedHeight(40)
        self.start_button.setStyleSheet(
            "QPushButton { background-color: #4CAF50; color: white; font-weight: bold; }")
        self.start_button.clicked.connect(self.start_robot)
        control_layout.addWidget(self.start_button)
        
        # 停止按钮
        self.stop_button = QPushButton("停止机器人")
        self.stop_button.setFixedHeight(40)
        self.stop_button.setStyleSheet(
            "QPushButton { background-color: #f44336; color: white; font-weight: bold; }")
        self.stop_button.clicked.connect(self.stop_robot)
        control_layout.addWidget(self.stop_button)
        
        main_layout.addLayout(control_layout)
        
        # 状态信息区域
        self.status_widget = QGroupBox("机器人状态")
        status_layout = QVBoxLayout()
        
        # 状态指示器
        status_h_layout = QHBoxLayout()
        
        # 状态标签
        self.status_label = QLabel("已停止")
        self.status_label.setFixedWidth(100)
        
        # 状态灯
        self.status_indicator = QLabel()
        self.status_indicator.setFixedSize(20, 20)
        self._update_status_indicator(False)
        
        status_h_layout.addWidget(QLabel("状态:"))
        status_h_layout.addWidget(self.status_label)
        status_h_layout.addWidget(self.status_indicator)
        status_h_layout.addStretch()
        
        status_layout.addLayout(status_h_layout)
        
        # 运行时间
        self.run_time_label = QLabel("运行时间: 00:00:00")
        status_layout.addWidget(self.run_time_label)
        
        # 任务统计
        self.tasks_label = QLabel("任务统计: 0 执行, 0 成功, 0 失败")
        status_layout.addWidget(self.tasks_label)
        
        # 进度条
        self.progress_bar = QProgressBar()
        self.progress_bar.setRange(0, 100)
        self.progress_bar.setValue(0)
        self.progress_bar.setTextVisible(True)
        self.progress_bar.setFormat("空闲")
        status_layout.addWidget(self.progress_bar)
        
        # 日志输出
        self.log_text = QTextEdit()
        self.log_text.setReadOnly(True)
        self.log_text.setFixedHeight(150)
        status_layout.addWidget(QLabel("最近日志:"))
        status_layout.addWidget(self.log_text)
        
        self.status_widget.setLayout(status_layout)
        main_layout.addWidget(self.status_widget)
        
        # 添加伸展空间
        main_layout.addStretch()
    
    def _init_timer(self):
        """初始化定时器"""
        # 状态更新定时器
        self._status_timer = QTimer(self)
        self._status_timer.timeout.connect(self._update_status)
        self._status_timer.start(1000)  # 每秒更新一次
    
    def _update_ui_state(self):
        """更新UI状态"""
        is_running = self.robot is not None and self.robot.is_running
        
        # 更新按钮状态
        self.start_button.setEnabled(not is_running)
        self.stop_button.setEnabled(is_running)
        
        # 更新配置编辑状态
        self.name_edit.setEnabled(not is_running)
        self.description_edit.setEnabled(not is_running)
        self.retry_spin.setEnabled(not is_running)
        self.retry_interval_spin.setEnabled(not is_running)
        self.timeout_spin.setEnabled(not is_running)
        
        # 更新状态标签和指示器
        self.status_label.setText("运行中" if is_running else "已停止")
        self._update_status_indicator(is_running)
    
    def _update_status_indicator(self, is_running):
        """更新状态指示器颜色"""
        color = QColor("#4CAF50") if is_running else QColor("#f44336")
        palette = QPalette()
        palette.setColor(QPalette.ColorRole.WindowText, color)
        self.status_indicator.setPalette(palette)
        self.status_indicator.setText("●")
        self.status_indicator.setFont(QFont("Arial", 16))
    
    def _update_status(self):
        """更新状态信息"""
        if self.robot and self.robot.is_running:
            # 更新运行时间
            run_time = self.robot.run_time
            hours, remainder = divmod(int(run_time), 3600)
            minutes, seconds = divmod(remainder, 60)
            time_str = f"运行时间: {hours:02d}:{minutes:02d}:{seconds:02d}"
            self.run_time_label.setText(time_str)
            
            # 更新任务统计
            tasks_str = f"任务统计: {self.robot.executed_tasks_count} 执行, "
            tasks_str += f"{self.robot.successful_tasks_count} 成功, "
            tasks_str += f"{self.robot.failed_tasks_count} 失败"
            self.tasks_label.setText(tasks_str)
            
            # 更新进度条（如果有正在执行的任务）
            # 这里简化处理，实际应该根据任务进度来更新
            self.progress_bar.setFormat("运行中")
        else:
            self.run_time_label.setText("运行时间: 00:00:00")
            self.tasks_label.setText("任务统计: 0 执行, 0 成功, 0 失败")
            self.progress_bar.setValue(0)
            self.progress_bar.setFormat("空闲")
    
    def start_robot(self):
        """启动机器人"""
        try:
            # 获取配置信息
            name = self.name_edit.text().strip()
            description = self.description_edit.text().strip()
            retry_count = self.retry_spin.value()
            retry_interval = self.retry_interval_spin.value()
            default_timeout = self.timeout_spin.value()
            
            # 验证配置
            if not name:
                logger.warning("机器人名称不能为空")
                return
            
            # 创建机器人实例
            self.robot = Robot(
                name=name,
                description=description,
                retry_count=retry_count,
                retry_interval=retry_interval,
                default_timeout=default_timeout
            )
            
            # 创建并启动线程
            self._robot_thread = threading.Thread(
                target=self._run_robot, 
                daemon=True
            )
            self._robot_thread.start()
            
            # 等待机器人启动
            time.sleep(0.1)
            
            # 更新UI状态
            self._update_ui_state()
            
            # 添加日志
            self._add_log(f"机器人 '{name}' 正在启动...")
            
            # 发送信号
            self.robot_started.emit(self.robot)
            
        except Exception as e:
            logger.error(f"启动机器人失败: {e}")
            self._add_log(f"错误: 启动机器人失败 - {str(e)}")
            self.robot = None
            self._update_ui_state()
            self.robot_error.emit(str(e))
    
    def _run_robot(self):
        """在独立线程中运行机器人"""
        try:
            # 启动机器人
            self.robot.start()
            self._add_log(f"机器人 '{self.robot.name}' 已成功启动")
            
            # 保持线程运行直到机器人停止
            while self.robot.is_running:
                time.sleep(0.5)
                
        except RobotExecutionException as e:
            logger.error(f"机器人执行错误: {e}")
            self._add_log(f"错误: 机器人执行错误 - {str(e)}")
            self.robot_error.emit(str(e))
        except Exception as e:
            logger.error(f"机器人运行错误: {e}")
            self._add_log(f"错误: 机器人运行错误 - {str(e)}")
            self.robot_error.emit(str(e))
        finally:
            # 确保机器人停止
            if self.robot and self.robot.is_running:
                self.robot.stop()
            
            # 更新UI状态
            self._update_ui_state()
            
            # 发送停止信号
            self.robot_stopped.emit()
    
    def stop_robot(self):
        """停止机器人"""
        try:
            if self.robot and self.robot.is_running:
                self._add_log(f"正在停止机器人 '{self.robot.name}'...")
                
                # 停止机器人
                self.robot.stop()
                
                # 等待线程结束
                if self._robot_thread:
                    self._robot_thread.join(timeout=5)
                
                self._add_log(f"机器人 '{self.robot.name}' 已停止")
                
                # 更新UI状态
                self._update_ui_state()
                
                # 发送停止信号
                self.robot_stopped.emit()
                
                # 清除机器人实例
                self.robot = None
                self._robot_thread = None
            else:
                logger.warning("机器人未运行")
        except Exception as e:
            logger.error(f"停止机器人失败: {e}")
            self._add_log(f"错误: 停止机器人失败 - {str(e)}")
            self.robot_error.emit(str(e))
    
    def _add_log(self, message):
        """添加日志消息到界面"""
        # 获取当前时间
        current_time = time.strftime("%H:%M:%S")
        
        # 添加日志消息
        log_message = f"[{current_time}] {message}\n"
        self.log_text.insertPlainText(log_message)
        
        # 滚动到底部
        self.log_text.moveCursor(self.log_text.textCursor().End)
        
        # 限制日志行数
        lines = self.log_text.toPlainText().splitlines()
        if len(lines) > 50:  # 只保留最近50行日志
            self.log_text.setPlainText("\n".join(lines[-50:]))
            self.log_text.moveCursor(self.log_text.textCursor().End)
    
    def get_robot(self):
        """获取机器人实例"""
        return self.robot
    
    def is_robot_running(self):
        """检查机器人是否正在运行"""
        return self.robot is not None and self.robot.is_running